using Unity.Burst;
using Unity.Entities;
using Unity.Mathematics;
using Unity.Transforms;

namespace DOTS.DOD.LESSON8
{
    [BurstCompile]
    [RequireMatchingQueriesForUpdate]
    [UpdateInGroup(typeof(MultiCubesMarchSystemGroup))]
    partial struct MultiCubesGenerateSystem : ISystem
    {
        float mTimer;
        int mTotalCount;

        [BurstCompile]
        public void OnCreate(ref SystemState state)
        {
            state.RequireForUpdate<MultiCubesGenerator>();
            mTimer = 0f;
            mTotalCount = 0;
        }

        [BurstCompile]
        public void OnUpdate(ref SystemState state)
        {
            var generator = SystemAPI.GetSingleton<MultiCubesGenerator>();
            if (mTotalCount >= generator.GenerationTotalCount)
            {
                state.Enabled = false;
                return;
            }

            if (mTimer >= generator.TickTime)
            {
                GenerateCube(ref state, generator);
                mTimer -= generator.TickTime;
            }

            mTimer += SystemAPI.Time.DeltaTime;
        }

        void GenerateCube(ref SystemState state, MultiCubesGenerator generator)
        {
            Entity redCube = state.EntityManager.Instantiate(generator.RedCubeProtoType);
            Entity greenCube = state.EntityManager.Instantiate(generator.GreenCubeProtoType);
            Entity blueCube = state.EntityManager.Instantiate(generator.BlueCubeProtoType);

            state.EntityManager.AddSharedComponent(redCube, new CubeSharedComponentData()
            //state.EntityManager.AddComponentData(redCube, new CubeComponentData()
            {
                RotateSpeed = math.radians(180f),
                MoveSpeed = 5f,
                //避免大量有独特值的共享组件，会造成大量空置Chunk，大幅降低Chunk利用率，增加内存占用和CacheMissing
                //MoveSpeed = Random.CreateFromIndex((uint)mTotalCount).NextFloat(3f, 10f),
            });
            state.EntityManager.AddSharedComponent(redCube, new SharingGroup()
            {
                Group = 0,
            });

            state.EntityManager.AddSharedComponent(greenCube, new CubeSharedComponentData()
            //state.EntityManager.AddComponentData(greenCube, new CubeComponentData()
            {
                RotateSpeed = math.radians(180f),
                MoveSpeed = 5f,
                //MoveSpeed = Random.CreateFromIndex((uint)mTotalCount).NextFloat(3f, 8f),
            });
            state.EntityManager.AddSharedComponent(greenCube, new SharingGroup()
            {
                Group = 1,
            });

            state.EntityManager.AddSharedComponent(blueCube, new CubeSharedComponentData()
            //state.EntityManager.AddComponentData(blueCube, new CubeComponentData()
            {
                RotateSpeed = math.radians(180f),
                MoveSpeed = 5f,
                //MoveSpeed = Random.CreateFromIndex((uint)mTotalCount).NextFloat(3f, 6f),
            });
            state.EntityManager.AddSharedComponent(blueCube, new SharingGroup()
            {
                Group = 2,
            });

            var redCubeTransform = SystemAPI.GetComponentRW<LocalTransform>(redCube);
            redCubeTransform.ValueRW.Position = generator.RedCubeGeneratorPos;

            var greenCubeTransform = SystemAPI.GetComponentRW<LocalTransform>(greenCube);
            greenCubeTransform.ValueRW.Position = generator.GreenCubeGeneratorPos;

            var blueCubeTransform = SystemAPI.GetComponentRW<LocalTransform>(blueCube);
            blueCubeTransform.ValueRW.Position = generator.BlueCubeGeneratorPos;

            mTotalCount += 3;
        }
    }
}